﻿// CDoubleList.cpp: 实现文件
//

#include "pch.h"
#include "MY_PE_TOOL.h"
#include "CDoubleList.h"
#include "afxdialogex.h"
#include "MY_PE_TOOLDlg.h"
#include "CDlgMyAddImport.h"


// CDoubleList 对话框

IMPLEMENT_DYNAMIC(CDoubleList, CDialogEx)

CDoubleList::CDoubleList(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG1, pParent)
{

}

CDoubleList::~CDoubleList()
{
}

void CDoubleList::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_LIST1, m_UpListCtrl);
    DDX_Control(pDX, IDC_LIST2, m_DownListCtrl);
}


BEGIN_MESSAGE_MAP(CDoubleList, CDialogEx)
    ON_WM_SIZE()
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CDoubleList::OnItemchangedList1)
    ON_NOTIFY(NM_CLICK, IDC_LIST1, &CDoubleList::OnClickList1)
    ON_NOTIFY(NM_CLICK, IDC_LIST2, &CDoubleList::OnClickList2)
    ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CDoubleList::OnRclickList1)
    ON_COMMAND(MN_ADDIMPORT, &CDoubleList::OnAddimport)
END_MESSAGE_MAP()


// CDoubleList 消息处理程序


//根据RVA计算FA
DWORD CDoubleList::RVATOFA(DWORD dwRVA)
{
    PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
    PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
    PIMAGE_SECTION_HEADER pSectionHead = (PIMAGE_SECTION_HEADER)((DWORD)&pNtHead->OptionalHeader + pNtHead->FileHeader.SizeOfOptionalHeader);

    //在节表中
    for (int i = 0; i < pNtHead->FileHeader.NumberOfSections; i++)
    {
        //判断该RVA是否在这个节区中
        if (dwRVA >= pSectionHead[i].VirtualAddress && dwRVA < pSectionHead[i].VirtualAddress + pSectionHead[i].SizeOfRawData)
        {
            return (dwRVA - pSectionHead[i].VirtualAddress + pSectionHead[i].PointerToRawData);
        }
    }

    return 0;
}

//将数字转换为字符串
CString CDoubleList::IntToString(DWORD nData, DWORD nLen)
{
    nLen *= 2;

    CString strFmt;
    strFmt.Format(_T("%%0%dX"), nLen);

    CString strRet;
    strRet.Format(strFmt, nData);

    return strRet;
}

void CDoubleList::ClearUpListCtrl()
{
    m_UpListCtrl.DeleteAllItems();
    int nColumnCount = m_UpListCtrl.GetHeaderCtrl()->GetItemCount();
    for (int i = 0; i < nColumnCount; i++)
    {
        m_UpListCtrl.DeleteColumn(0);
    }
}

void CDoubleList::ClearDownListCtrl()
{
    m_DownListCtrl.DeleteAllItems();
    int nColumnCount = m_DownListCtrl.GetHeaderCtrl()->GetItemCount();
    for (int i = 0; i < nColumnCount; i++)
    {
        m_DownListCtrl.DeleteColumn(0);
    }
}

void CDoubleList::UpListInsertColumn()
{
    m_UpListCtrl.InsertColumn(0, _T("Module Name"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(1, _T("OriginalFirstThunk"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(2, _T("TimeDateStamp"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(3, _T("ForwarderChain"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(4, _T("Name RVA"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(5, _T("FirstThunk (IAT)"), LVCFMT_LEFT, 150);

    //将第一行空出来
    m_UpListCtrl.InsertItem(0, _T("szAnsi"));
    for (int i = 0; i < 6; i++)
    {
        BOOL n = m_UpListCtrl.SetItemText(0, i, _T(" "));
    }

    //显示第二行的长度
    m_UpListCtrl.InsertItem(1, _T("szAnsi"));
    m_UpListCtrl.SetItemText(1, 1, _T("DWORD"));
    m_UpListCtrl.SetItemText(1, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(1, 3, _T("DWORD"));
    m_UpListCtrl.SetItemText(1, 4, _T("DWORD"));
    m_UpListCtrl.SetItemText(1, 5, _T("DWORD"));
}

void CDoubleList::DownListInsertColumn()
{
    m_DownListCtrl.InsertColumn(0, _T("OFT"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(1, _T("FT (IAT)"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(2, _T("Hint"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(3, _T("Name"), LVCFMT_LEFT, 150);

    //将第一行空出来
    m_DownListCtrl.InsertItem(0, _T("szAnsi"));
    for (int i = 0; i < 4; i++)
    {
        BOOL n = m_DownListCtrl.SetItemText(0, i, _T(" "));
    }

    //显示第二行的长度
    m_DownListCtrl.InsertItem(1, _T("DWORD"));
    m_DownListCtrl.SetItemText(1, 1, _T("DWORD"));
    m_DownListCtrl.SetItemText(1, 2, _T("WORD"));
    m_DownListCtrl.SetItemText(1, 3, _T("szAnsi"));
}


void CDoubleList::UpListInsertExport()
{
    m_UpListCtrl.InsertColumn(0, _T("Member"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(1, _T("Offset"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(2, _T("Size"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(3, _T("Value"), LVCFMT_LEFT, 150);
}

void CDoubleList::DownListInsertExport()
{
    m_DownListCtrl.InsertColumn(0, _T("Ordinal"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(1, _T("Function RVA"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(2, _T("Name Ordinal"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(3, _T("Name RVA"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(4, _T("Name"), LVCFMT_LEFT, 150);
}

void CDoubleList::UpListInsertReloc()
{
    m_UpListCtrl.InsertColumn(0, _T("RVA"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(1, _T("Size Of Block"), LVCFMT_LEFT, 150);
    m_UpListCtrl.InsertColumn(2, _T("Items"), LVCFMT_LEFT, 150);
}

void CDoubleList::DownListInsertReloc()
{
    m_DownListCtrl.InsertColumn(0, _T("Item"), LVCFMT_LEFT, 150);
    m_DownListCtrl.InsertColumn(1, _T("RVA"), LVCFMT_LEFT, 150);
}

//展示导入表项
void CDoubleList::ShowImportItem()
{
    //显示每个成员的大小（BYTE WORD DWORD）
    int nRow = 2;

    //定位导入表
    PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
    PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
    DWORD dwImportRVA = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    DWORD dwImportSize = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;

    PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(RVATOFA(dwImportRVA) + (DWORD)pDosHead);
    DWORD dwImportNum = dwImportSize / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1;

    for (int i = 0; i < dwImportNum; i++)
    {
        char* pDllName = (char*)(RVATOFA(pImportDescriptor[i].Name) + (DWORD)pDosHead);
        m_UpListCtrl.InsertItem(nRow, CString(pDllName));
        m_UpListCtrl.SetItemText(nRow, 1, IntToString(pImportDescriptor[i].OriginalFirstThunk, sizeof(pImportDescriptor[i].OriginalFirstThunk)));
        m_UpListCtrl.SetItemText(nRow, 2, IntToString(pImportDescriptor[i].TimeDateStamp, sizeof(pImportDescriptor[i].TimeDateStamp)));
        m_UpListCtrl.SetItemText(nRow, 3, IntToString(pImportDescriptor[i].ForwarderChain, sizeof(pImportDescriptor[i].ForwarderChain)));
        m_UpListCtrl.SetItemText(nRow, 4, IntToString(pImportDescriptor[i].Name, sizeof(pImportDescriptor[i].Name)));
        m_UpListCtrl.SetItemText(nRow++, 5, IntToString(pImportDescriptor[i].FirstThunk, sizeof(pImportDescriptor[i].FirstThunk)));
    }
}


//展示导出表项
void CDoubleList::ShowExportItem()
{
    int nRow = 0;

    //定位导出表
    PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
    PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
    DWORD dwExportRVA = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    DWORD dwExportSize = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

    PIMAGE_EXPORT_DIRECTORY pExportDescriptor = (PIMAGE_EXPORT_DIRECTORY)(RVATOFA(dwExportRVA) + (DWORD)pDosHead);

    m_UpListCtrl.InsertItem(nRow, _T("Characteristics"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->Characteristics - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->Characteristics, sizeof(pExportDescriptor->Characteristics)));

    m_UpListCtrl.InsertItem(nRow, _T("TimeDateStamp"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->TimeDateStamp - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->TimeDateStamp, sizeof(pExportDescriptor->TimeDateStamp)));

    m_UpListCtrl.InsertItem(nRow, _T("MajorVersion"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->MajorVersion - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("WORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->MajorVersion, sizeof(pExportDescriptor->MajorVersion)));

    m_UpListCtrl.InsertItem(nRow, _T("MinorVersion"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->MinorVersion - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("WORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->MinorVersion, sizeof(pExportDescriptor->MinorVersion)));

    m_UpListCtrl.InsertItem(nRow, _T("Name"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->Name - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->Name, sizeof(pExportDescriptor->Name)));

    m_UpListCtrl.InsertItem(nRow, _T("Base"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->Base - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->Base, sizeof(pExportDescriptor->Base)));

    m_UpListCtrl.InsertItem(nRow, _T("NumberOfFunctions"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->NumberOfFunctions - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->NumberOfFunctions, sizeof(pExportDescriptor->NumberOfFunctions)));

    m_UpListCtrl.InsertItem(nRow, _T("NumberOfNames"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->NumberOfNames - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->NumberOfNames, sizeof(pExportDescriptor->NumberOfNames)));

    m_UpListCtrl.InsertItem(nRow, _T("AddressOfFunctions"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->AddressOfFunctions - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->AddressOfFunctions, sizeof(pExportDescriptor->AddressOfFunctions)));

    m_UpListCtrl.InsertItem(nRow, _T("AddressOfNames"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->AddressOfNames - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->AddressOfNames, sizeof(pExportDescriptor->AddressOfNames)));

    m_UpListCtrl.InsertItem(nRow, _T("AddressOfNameOrdinals"));
    m_UpListCtrl.SetItemText(nRow, 1, IntToString((DWORD)&pExportDescriptor->AddressOfNameOrdinals - (DWORD)pDosHead, 4));
    m_UpListCtrl.SetItemText(nRow, 2, _T("DWORD"));
    m_UpListCtrl.SetItemText(nRow++, 3, IntToString(pExportDescriptor->AddressOfNameOrdinals, sizeof(pExportDescriptor->AddressOfNameOrdinals)));

    DWORD dwBase = pExportDescriptor->Base;
    DWORD* pdwAddrOfFun = (DWORD*)(RVATOFA(pExportDescriptor->AddressOfFunctions) + (DWORD)pDosHead);
    DWORD* pdwAddrName = (DWORD*)(RVATOFA(pExportDescriptor->AddressOfNames) + (DWORD)pDosHead);
    WORD* pdwAddrOrdinals = (WORD*)(RVATOFA(pExportDescriptor->AddressOfNameOrdinals) + (DWORD)pDosHead);

    int nDownRow = 0;
    BOOL bIsName = FALSE;

    for (int i = 0; i < pExportDescriptor->NumberOfFunctions; i++)
    {
        bIsName = FALSE;

        if (pdwAddrOfFun[i] == 0)
        {
            continue;
        }

        m_DownListCtrl.InsertItem(nDownRow, IntToString(i + dwBase, 4));
        m_DownListCtrl.SetItemText(nDownRow, 1, IntToString(pdwAddrOfFun[i], 4));

        for (int j = 0; j < pExportDescriptor->NumberOfNames; j++)
        {
            if (i == pdwAddrOrdinals[j])
            {
                bIsName = TRUE;
                m_DownListCtrl.SetItemText(nDownRow, 2, IntToString(pdwAddrOrdinals[j], 2));
                m_DownListCtrl.SetItemText(nDownRow, 3, IntToString(pdwAddrName[j], 4));
                char* pName = (char*)(RVATOFA(pdwAddrName[j]) + (DWORD)pDosHead);
                m_DownListCtrl.SetItemText(nDownRow++, 4, CString(pName));
                break;
            }
        }

        if (!bIsName)
        {
            m_DownListCtrl.SetItemText(nDownRow, 2, _T("N/A"));
            m_DownListCtrl.SetItemText(nDownRow, 3, _T("N/A"));
            m_DownListCtrl.SetItemText(nDownRow++, 4, _T("N/A"));
        }
    }

}


//展示重定位目录
void CDoubleList::ShowReloctionItem()
{
    int nRow = 0;

    //定位导入表
    PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
    PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
    DWORD dwRelocRVA = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    DWORD dwRelocSize = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

    PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)(RVATOFA(dwRelocRVA) + (DWORD)pDosHead);

    DWORD dwNowRelocSize = 0;

    while (dwNowRelocSize < dwRelocSize)
    {
        //计算页内偏移有多少个需要重定位
        int nCount = (pRelocation->SizeOfBlock - 8) / 2;

        m_UpListCtrl.InsertItem(nRow, IntToString(pRelocation->VirtualAddress, 4));
        m_UpListCtrl.SetItemText(nRow, 1, IntToString(pRelocation->SizeOfBlock, 4));
        CString strFmt;
        strFmt.Format(_T("%d"), nCount);
        m_UpListCtrl.SetItemText(nRow++, 2, strFmt);

        dwNowRelocSize += pRelocation->SizeOfBlock;
        pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock);
    }
}


//展示函数名称等信息
void CDoubleList::ShowFunNameAlso(DWORD dwCount)
{
    ClearDownListCtrl();
    DownListInsertColumn();

    int nRow = 2;
    int nCount = 0;

    PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
    PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
    DWORD dwImportRVA = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    DWORD dwImportSize = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;

    PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(RVATOFA(dwImportRVA) + (DWORD)pDosHead);
    
    DWORD dwINTFA = RVATOFA(pImportDescriptor[dwCount].OriginalFirstThunk);
    DWORD dwIATFA = RVATOFA(pImportDescriptor[dwCount].FirstThunk);
    dwINTFA = dwINTFA + (DWORD)pDosHead;
    dwIATFA = dwIATFA + (DWORD)pDosHead;

    while (TRUE)
    {
        if (((DWORD*)dwIATFA)[nCount] == 0)
        {
            break;
        }

        //名称导入
        if (((DWORD*)dwINTFA)[nCount] >> 31 == 0)
        {
            m_DownListCtrl.InsertItem(nRow, IntToString(((DWORD*)dwINTFA)[nCount], 4));
            m_DownListCtrl.SetItemText(nRow, 1, IntToString(((DWORD*)dwIATFA)[nCount], 4));

            DWORD dwMyRva = RVATOFA(((DWORD*)dwINTFA)[nCount]);
            PIMAGE_IMPORT_BY_NAME pImportByName = (PIMAGE_IMPORT_BY_NAME)(dwMyRva + (DWORD)pDosHead);

            m_DownListCtrl.SetItemText(nRow, 2, IntToString(pImportByName->Hint, 2));
            m_DownListCtrl.SetItemText(nRow++, 3, CString(pImportByName->Name));

            nCount++;
        }
        //序号导入
        else
        {
            m_DownListCtrl.InsertItem(nRow, IntToString(((DWORD*)dwINTFA)[nCount], 4));
            m_DownListCtrl.SetItemText(nRow, 1, IntToString(((DWORD*)dwIATFA)[nCount], 4));

            m_DownListCtrl.SetItemText(nRow, 2, _T("N/A"));
            m_DownListCtrl.SetItemText(nRow++, 3, IntToString(((DWORD*)dwINTFA)[nCount] & 0x7FFFFFFF, 4));

            nCount++;
        }

    }


    //pImportDescriptor[dwCount]
}


void CDoubleList::SetFileData(char** pFileData)
{
    m_pFileData = pFileData;
}

void CDoubleList::SetFilePath(TCHAR* pFilePath)
{
    m_pFileFullPath = pFilePath;
}


void CDoubleList::SetTreeItemText(CString* pTreeItem)
{
    m_pTreeItemText = pTreeItem;
}

//显示导入表
void CDoubleList::ShowImportTable()
{
    //清空列表项
    ClearUpListCtrl();
    ClearDownListCtrl();

    //添加表头
    UpListInsertColumn();
    DownListInsertColumn();

    //展示导入表项
    ShowImportItem();
}


//显示导出表
void CDoubleList::ShowExportTable()
{
    //清空列表项
    ClearUpListCtrl();
    ClearDownListCtrl();

    //添加表头
    UpListInsertExport();
    DownListInsertExport();

    //展示导出表项
    ShowExportItem();
}


//展示重定位目录
void CDoubleList::ShowReloctionTable()
{
    //清空列表项
    ClearUpListCtrl();
    ClearDownListCtrl();

    //添加表头
    UpListInsertReloc();
    DownListInsertReloc();

    //展示导出表项
    ShowReloctionItem();
}


BOOL CDoubleList::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    //设置ListCtrl的风格
    m_UpListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    m_DownListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

    return TRUE;  // return TRUE unless you set the focus to a control
                  // 异常: OCX 属性页应返回 FALSE
}


void CDoubleList::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);

    if (m_UpListCtrl)
    {
        CRect rect;
        GetClientRect(rect);
        rect.bottom /= 2;
        rect.bottom -= 2;
        m_UpListCtrl.MoveWindow(rect);
    }
    if (m_DownListCtrl)
    {
        CRect rect;
        GetClientRect(rect);
        rect.top = rect.bottom / 2 + 2;
        m_DownListCtrl.MoveWindow(rect);
    }
}


void CDoubleList::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

    CMYPETOOLDlg* Parent = (CMYPETOOLDlg*)GetParent();

    if (m_UpListCtrl.GetItemCount() > 1)
    {
        //Parent->OnLvnItemchangedList2(pNMHDR, pResult);
    }

    *pResult = 0;
}


//左键单击 UPLIST
void CDoubleList::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    *pResult = 0;

    if (*m_pTreeItemText == _T("导出目录"))
    {
        return;
    }

    if (*m_pTreeItemText == _T("重定位目录"))
    {
        //判断左键单击的项
        int nRow = pNMItemActivate->iItem;
        if (nRow == -1)
        {
            return;
        }

        ClearDownListCtrl();
        DownListInsertReloc();
        //定位导入表
        PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
        PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
        PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
        DWORD dwRelocRVA = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
        DWORD dwRelocSize = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

        PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)(RVATOFA(dwRelocRVA) + (DWORD)pDosHead);

        DWORD dwNowRelocSize = 0;

        int nNowRow = 0;
        int nCout = 0;
        WORD* pwTypeOffset = NULL;
        while (dwNowRelocSize < dwRelocSize)
        {
            if (nCout == nRow)
            {
                //计算页内偏移有多少个需要重定位
                int nCount = (pRelocation->SizeOfBlock - 8) / 2;

                //页内偏移数组地址
                pwTypeOffset = (WORD*)((DWORD)pRelocation + 8);
  
                for (int i = 0; i < nCount; i++)
                {
                    //计算页内偏移
                    WORD wOffset = pwTypeOffset[i] & 0x0fff;
                    
                    m_DownListCtrl.InsertItem(nNowRow, IntToString(pwTypeOffset[i], 2));
                    m_DownListCtrl.SetItemText(nNowRow++, 1, IntToString(wOffset + pRelocation->VirtualAddress, 4));
                }
            }

            dwNowRelocSize += pRelocation->SizeOfBlock;
            pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock);

            nCout++;
        }

    }
    else
    {
        //先将显示的偏移值清空
        for (int i = 0; i < 6; i++)
        {
            BOOL n = m_UpListCtrl.SetItemText(0, i, _T(" "));
        }

        //判断左键单击的项
        int nRow = pNMItemActivate->iItem;

        //如果没有选中导入表项
        if (nRow < 2)
        {
            return;
        }

        //显示偏移
        PIMAGE_DOS_HEADER pDosHead = (PIMAGE_DOS_HEADER)(*m_pFileData);
        PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + pDosHead->e_lfanew);
        PIMAGE_OPTIONAL_HEADER32 pOptionalHead = &pNtHead->OptionalHeader;
        DWORD dwImportRVA = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        DWORD dwImportSize = pOptionalHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;

        PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(RVATOFA(dwImportRVA) + (DWORD)pDosHead);
        DWORD dwImportNum = dwImportSize / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1;
        DWORD dwItem = nRow - 2;

        //如果选择超出导入表项
        if (dwItem + 1 > dwImportNum)
        {
            return;
        }

        //显示偏移
        m_UpListCtrl.SetItemText(0, 0, IntToString(RVATOFA(pImportDescriptor[dwItem].Name), 4));
        m_UpListCtrl.SetItemText(0, 1, IntToString((DWORD) & (pImportDescriptor[dwItem].OriginalFirstThunk) - (DWORD)pDosHead, 4));
        m_UpListCtrl.SetItemText(0, 2, IntToString((DWORD) & (pImportDescriptor[dwItem].TimeDateStamp) - (DWORD)pDosHead, 4));
        m_UpListCtrl.SetItemText(0, 3, IntToString((DWORD) & (pImportDescriptor[dwItem].ForwarderChain) - (DWORD)pDosHead, 4));
        m_UpListCtrl.SetItemText(0, 4, IntToString((DWORD) & (pImportDescriptor[dwItem].Name) - (DWORD)pDosHead, 4));
        m_UpListCtrl.SetItemText(0, 5, IntToString((DWORD) & (pImportDescriptor[dwItem].FirstThunk) - (DWORD)pDosHead, 4));

        //DwonList显示相关信息
        ShowFunNameAlso(dwItem);
    }

}


//
void CDoubleList::OnClickList2(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);



    *pResult = 0;
}


//右键单击
void CDoubleList::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

    //设置鼠标的坐标是相对于ListCtrl的
    m_UpListCtrl.ClientToScreen(&pNMItemActivate->ptAction);

    CMenu menu;

    if (*m_pTreeItemText == _T("导入目录"))
    {
        //从资源加载菜单
        menu.LoadMenu(IDR_MENU2);

        //获取子菜单
        CMenu* pSubMenu = menu.GetSubMenu(1);

        //弹出子菜单
        pSubMenu->TrackPopupMenu(
            TPM_LEFTALIGN,
            pNMItemActivate->ptAction.x,
            pNMItemActivate->ptAction.y,
            this);
    }

    *pResult = 0;
}


//增加一个导入表项
void CDoubleList::OnAddimport()
{
    CDlgMyAddImport DlgAddImport;
    DlgAddImport.SetFileData(m_pFileData);
    DlgAddImport.SetFilePath(m_pFileFullPath);
    DlgAddImport.DoModal();
}
